﻿using System;
using System.Collections.Generic;
using System.Linq;
using FluentlyXml.Core.BuiltInSerializers;
using FluentlyXml.Core.Deserialization;
using FluentlyXml.Core.Deserialization.BuiltInDeserializers;
using FluentlyXml.Core.Serialization;

namespace FluentlyXml.Core
{
	//TODO: Do we want to split this? 
	internal class RuntimeSerializationConfig : IRuntimeSerializationConfig, IRuntimeDeserializationConfig
	{
		private readonly IList<ITypeSerializer> _serializerTypes;
		private readonly IList<ITypeDeserializer> _deserializerTypes;

		public RuntimeSerializationConfig()
		{
			_serializerTypes = new List<ITypeSerializer> { new ArraySerializer() };

			_deserializerTypes = new List<ITypeDeserializer> { new ArrayDeserializer(), new ListDeserializer() };
		}

		#region Serialization Stuff

		public ITypeSerializer GetSerializerFor(Type type)
		{
			var serializer = _serializerTypes.FirstOrDefault(t => t.CanSerialize(type));

			if (serializer == null)
			{
				var config = new TypeSerializationConfig(type);
				serializer = config.BuildSerializer();
				AddSerializer(serializer);
			}

			return serializer;
		}

		public void AddSerializer(ITypeSerializer serializer)
		{
			_serializerTypes.Insert(0, serializer);
		}

		#endregion

		#region Deserialization Stuff

		public ITypeDeserializer GetDeserializerFor(Type type)
		{
			var deserializer = _deserializerTypes.FirstOrDefault(t => t.CanDeserialize(type));

			if (deserializer == null)
			{
				var config = new TypeDeserializationConfig(type);
				deserializer = config.BuildDeserializer();
				AddDeserializer(deserializer);
			}

			return deserializer;
		}

		public void AddDeserializer(ITypeDeserializer deserializer)
		{
			_deserializerTypes.Insert(0, deserializer);
		}

		#endregion
	}
}